//////////////////////////////////////////////////////////////////////////////////
//	Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#include <wx/wx.h>
#include "rcmdapp.h"
#include "mainwnd.h"
#include "guilogic.h"
#include "perfomancetab.h"
#include "statuspanel.h"
#include "propertystorage.h"
#include "routercaps.h"

CPerfomanceTab::CPerfomanceTab(wxWindow* pParent, CGUILogic& logic, class CPropertyStorage& propStorage):wxPanel(pParent), m_logic(logic),
	m_statCon(NULL), m_statRTCache(NULL), m_statMemory(NULL), m_statCPU(NULL)
{
	wxBoxSizer* siser = new wxBoxSizer(wxVERTICAL);

	GUIBIND bind;

	unsigned int nSizerFlags = wxLEFT|wxRIGHT|wxEXPAND; /*wxALL|wxALIGN_CENTER_VERTICAL*/
	unsigned int nPropFlag   = 1;
	unsigned int nBorder=10;

	if ( CRouterCaps::GetIntstance().HasNATUsageInfo() )
	{
		//NAT
		m_statCon = new CStatusPanel(this, wxID_ANY, CGUILogic::PanelToName(cPTNAT) );
		siser->Add(m_statCon, nPropFlag, nSizerFlags, nBorder);

		bind.codeMaxVal = cCmdConntracMax;
		bind.codeVal    = cCmdGetSlabTable;
		bind.SetBinding(m_statCon->GetBind());
		bind.pStorage	= &propStorage;
		bind.plType		= cPTNAT;
		logic.AddBind( bind );
	}

	if ( CRouterCaps::GetIntstance().HasMEMUsageInfo() )
	{
		//Memory
		m_statMemory = new CStatusPanel(this, wxID_ANY, CGUILogic::PanelToName(cPTMem) );
		siser->Add(m_statMemory, nPropFlag, nSizerFlags, nBorder);

		bind.codeMaxVal = cCmdMemMax;
		bind.codeVal    = cCmdMemVal;
		bind.SetBinding(m_statMemory->GetBind());
		bind.pStorage	= &propStorage;
		bind.plType		= cPTMem;
		logic.AddBind( bind );
	}

	if ( CRouterCaps::GetIntstance().HasRTUsageInfo() )
	{
		//Routing
		m_statRTCache = new CStatusPanel(this, wxID_ANY, CGUILogic::PanelToName(cPTRoute) );
		siser->Add(m_statRTCache, nPropFlag, nSizerFlags, nBorder);

		bind.codeMaxVal = cCmdRTCacheMax;
		bind.codeVal    = cCmdRTCacheVal;
		bind.SetBinding(m_statRTCache->GetBind());
		bind.pStorage	= &propStorage;
		bind.plType		= cPTRoute;
		logic.AddBind( bind );
	}

	if ( CRouterCaps::GetIntstance().HasCPUUsageInfo() )
	{
		//CPU
		m_statCPU = new CStatusPanel(this, wxID_ANY, CGUILogic::PanelToName(cPTCPU) );
		siser->Add(m_statCPU, nPropFlag, nSizerFlags, nBorder);

		bind.codeMaxVal = cCmdCPU;
		bind.codeVal    = cCmdCPU;
		bind.SetBinding( m_statCPU->GetBind());
		bind.pStorage	= &propStorage;
		bind.plType		= cPTCPU;
		logic.AddBind( bind );
	}

	//Stat
	m_srStat = new wxBoxSizer(wxHORIZONTAL);

	int nSpacerW = 20;
	wxChar* pDef = wxT("         0");
	wxSize sz = wxSize(50, wxDefaultSize.y);

	int nRVFlag = wxALIGN_RIGHT|wxFIXED_MINSIZE;

	wxStaticBoxSizer* pszNAT = new wxStaticBoxSizer( new
		wxStaticBox(this, wxID_ANY,  _("NAT Table")), wxVERTICAL);
	{
		wxFlexGridSizer* pGrid = new wxFlexGridSizer(6, 3, 4, 10);

		wxStaticText* pTxt = new wxStaticText(this, wxID_ANY, _("Total:"));
		m_pTxtNatMAX = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtNatMAX, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Used:"));
		m_pTxtNatCur = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT  );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtNatCur, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Leaked:"));
		m_pTxtNatLeak = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtNatLeak, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Repaired:"));
		m_pTxtNatRepCnt = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtNatRepCnt, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Rebooted:"));
		m_pTxtNatRebootCnt = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtNatRebootCnt, 0, nRVFlag);

		pszNAT->Add(pGrid);
	}
	m_srStat->Add(pszNAT,0, wxUP|wxRIGHT, 5);


	wxStaticBoxSizer* pszMem = new wxStaticBoxSizer( new
		wxStaticBox(this, wxID_ANY,  _("Memory")), wxVERTICAL);
	{
		wxFlexGridSizer* pGrid = new wxFlexGridSizer(5, 3, 4, 10);

		wxStaticText* pTxt = new wxStaticText(this, wxID_ANY, _("Total:"));
		m_pTxtMMMAX = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtMMMAX, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Used:"));
		m_pTxtMMCur = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtMMCur, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Free:"));
		m_pTxtMMFree = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtMMFree, 0, nRVFlag);


		pTxt = new wxStaticText(this, wxID_ANY, _("Usage:"));
		m_pTxtMMUsage = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtMMUsage, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Rebooted:"));
		m_pTxtMMRebootCnt = new wxStaticText(this, wxID_ANY,pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtMMRebootCnt, 0, nRVFlag);

		pszMem->Add(pGrid);
	}
	m_srStat->Add(pszMem, 0, wxUP|wxLEFT|wxRIGHT, 5);


	wxStaticBoxSizer* pszRT = new wxStaticBoxSizer( new
		wxStaticBox(this, wxID_ANY,  _("Routing Cache")), wxVERTICAL);
	{
		wxFlexGridSizer* pGrid = new wxFlexGridSizer(6, 3, 4, 10);

		wxStaticText* pTxt = new wxStaticText(this, wxID_ANY, _("Total:"));
		m_pTxtRTMAX = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtRTMAX, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Used:"));
		m_pTxtRTCur = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtRTCur, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Leaked:"));
		m_pTxtRTLeak = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtRTLeak, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Repaired:"));
		m_pTxtRTRepCnt = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtRTRepCnt, 0, nRVFlag);

		pTxt = new wxStaticText(this, wxID_ANY, _("Rebooted:"));
		m_pTxtRTRebootCnt = new wxStaticText(this, wxID_ANY, pDef, wxDefaultPosition, sz, wxST_NO_AUTORESIZE|wxALIGN_RIGHT );
		pGrid->Add(pTxt, 0, wxALIGN_LEFT);
		pGrid->Add(nSpacerW, 0);
		pGrid->Add(m_pTxtRTRebootCnt, 0, nRVFlag);

		pszRT->Add(pGrid);
	}
	m_srStat->Add(pszRT,0, wxUP|wxLEFT|wxRIGHT, 5);

	siser->Add(m_srStat, nPropFlag, wxLEFT, 14);
	SetSizer(siser);

	//SetVal( wxT("<state><nat boot_cnt='123456789' repair_cnt='n/a' sizechange_cnt='n/a' total_cnt='n/a' used_cnt='n/a' alloc_cnt='n/a' leaked='n/a'/><rt boot_cnt='454545450' repair_cnt='0' sizechange_cnt='0' total_cnt='0' used_cnt='0' alloc_cnt='0' leaked='0'/><mem boot_cnt='0' total_cnt='0' used_cnt='0' free='0' usage='00 %'/><cpu boot_cnt='0' total_cnt='0' used_cnt='0'/></state>") );
}

CPerfomanceTab::~CPerfomanceTab(void)
{
}

wxString CPerfomanceTab::GetLog()
{
	wxString strStatus;
	wxString str;

	if ( wxGetApp().GetMainWnd()->GetPropStorage().GetEnablePerfomanceLog() )
	{
		GUIBIND bindOut;

		//NAT
		if ( m_logic.GetBind( bindOut, m_statCon ) )
		{
			str=m_logic.GenerateStatusString(bindOut);
			strStatus+=str;
			strStatus+=wxT(", ");
		}

		//Memmory
		if ( m_logic.GetBind( bindOut, m_statMemory ) )
		{
			str=m_logic.GenerateStatusString(bindOut);
			strStatus+=str;
			strStatus+=wxT(", ");
		}

		//Routing
		if ( m_logic.GetBind( bindOut, m_statRTCache ) )
		{
			str=m_logic.GenerateStatusString(bindOut);
			strStatus+=str;
			strStatus+=wxT(", ");
		}

		//CPU
		if ( m_logic.GetBind( bindOut, m_statCPU ) )
		{
			str=m_logic.GenerateStatusString(bindOut);
			strStatus+=str;
		}
	}

	return strStatus;
}

void  CPerfomanceTab::SetVal(const wxString& str)
{
	CMarkupSTL	doc;
	
	if ( doc.SetDoc(str.ToAscii()) )
	{
		if ( doc.FindChildElem(STATE_NAT_EL) )
		{
			m_pTxtNatMAX->SetLabel( FormatValue(doc, STATE_TOTAL_CNT) ); 
			m_pTxtNatCur->SetLabel( FormatValue(doc, STATE_USED_CNT) ); 
			m_pTxtNatLeak->SetLabel( FormatValue(doc, STATE_LEAK_CNT) ); 
			m_pTxtNatRepCnt->SetLabel( FormatValue(doc, STATE_REPAIR_CNT) ); 
			m_pTxtNatRebootCnt->SetLabel( FormatValue(doc, STATE_BOOT_CNT) );
		}
		
		if ( doc.FindChildElem(STATE_RT_EL) )
		{
			m_pTxtRTMAX->SetLabel( FormatValue(doc, STATE_TOTAL_CNT) ); 
			m_pTxtRTCur->SetLabel( FormatValue(doc, STATE_USED_CNT) ); 
			m_pTxtRTLeak->SetLabel( FormatValue(doc, STATE_LEAK_CNT) ); 
			m_pTxtRTRepCnt->SetLabel( FormatValue(doc, STATE_REPAIR_CNT) ); 
			m_pTxtRTRebootCnt->SetLabel( FormatValue(doc, STATE_BOOT_CNT) );
		}
		
		if ( doc.FindChildElem(STATE_MEM_EL) )
		{
			m_pTxtMMMAX->SetLabel( FormatValue(doc, STATE_TOTAL_CNT) ); 
			m_pTxtMMCur->SetLabel( FormatValue(doc, STATE_USED_CNT) ); 
			m_pTxtMMUsage->SetLabel( FormatValue(doc, STATE_USAGE) ); 
			m_pTxtMMFree->SetLabel( FormatValue(doc, STATE_FREE) ); 
			m_pTxtMMRebootCnt->SetLabel( FormatValue(doc, STATE_BOOT_CNT) );
		}
	}

	m_srStat->CalcMin();
	m_srStat->RecalcSizes();
}

wxString CPerfomanceTab::FormatValue(class CMarkupSTL&	doc, const char* szXMLTag)
{
	wxString strVal = wxString::FromAscii( doc.GetChildAttrib(szXMLTag).c_str() );

	return wxString::Format(wxT("%s"), strVal.c_str());
}